package com.roamer.javase.demo.message.service;

import com.roamer.javase.demo.message.dto.MessagePageQueryDTO;
import com.roamer.javase.demo.message.entity.MessageEntity;
import com.roamer.javase.demo.message.vo.MessageForDayVO;

import java.util.*;
import java.util.concurrent.*;

/**
 * @author roamer
 * @version v1.0
 * @date 2020/3/20 22:13
 */
public class IService {

    private MessageService messageService = new MessageService();

    public static void main(String[] args) throws InterruptedException {
        long startTime = System.currentTimeMillis();
        IService service = new IService();
        service.messages(new MessagePageQueryDTO());
        System.out.println(System.currentTimeMillis() - startTime);
    }

    public Map<Integer, List<MessageForDayVO>> messages(MessagePageQueryDTO messagePageQueryDTO) throws InterruptedException {
        // 获取设备ID
        List<Long> deviceList = messageService.getDeviceIdList();
        if (deviceList.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<Integer, List<MessageForDayVO>> resultList = new TreeMap<>();
        // 创建线程池从hbase中获取数据,核心和最大线程数为2，超出队列的，由当前调用线程执行
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 2, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(deviceList.size()), new ThreadPoolExecutor.CallerRunsPolicy());
        try {
            // 添加任务并收集future
            List<Future<List<MessageEntity>>> futureList = new ArrayList<>(deviceList.size());
            for (Long id : deviceList) {
                futureList.add(poolExecutor.submit(new Callable<List<MessageEntity>>() {
                    @Override
                    public List<MessageEntity> call() throws InterruptedException {
                        return messageService.getDeviceInfo(id);
                    }
                }));
            }
            // 循环任务结果
            while (futureList.size() > 0) {
                Iterator<Future<List<MessageEntity>>> it = futureList.iterator();
                Future<List<MessageEntity>> future;
                // 已完成并且不是取消的
                while (it.hasNext() && null != (future = it.next()) && future.isDone() && !future.isCancelled()) {
                    List<MessageEntity> baseList = future.get();
                    for (MessageEntity message : baseList) {
                        // 获取小时
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(message.getCreateDate());
                        int hour = calendar.get(Calendar.HOUR_OF_DAY);
                        // 获取小时对应的数组，不存在则创建
                        List<MessageForDayVO> forDayList = resultList.get(hour);
                        if (forDayList == null) {
                            forDayList = new ArrayList<>();
                        }
                        // 转换并添加
                        MessageForDayVO forDayVO = new MessageForDayVO();
                        forDayVO.setGcId(message.getGcId());
                        forDayList.add(forDayVO);
                    }
                    it.remove();
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("执行异常", e);
        } finally {
            // 关闭线程池
            poolExecutor.shutdown();
        }
        return resultList;
    }

    public Map<Integer, List<MessageForDayVO>> messages2(MessagePageQueryDTO messagePageQueryDTO) throws InterruptedException {
        // 获取设备ID
        List<Long> deviceList = messageService.getDeviceIdList();
        if (deviceList.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<Integer, List<MessageForDayVO>> resultList = new TreeMap<>();
        // 添加任务并收集future
        for (Long id : deviceList) {
            List<MessageEntity> baseList = messageService.getDeviceInfo(id);
            for (MessageEntity message : baseList) {
                // 获取小时
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(message.getCreateDate());
                int hour = calendar.get(Calendar.HOUR_OF_DAY);
                // 获取小时对应的数组，不存在则创建
                List<MessageForDayVO> forDayList = resultList.get(hour);
                if (forDayList == null) {
                    forDayList = new ArrayList<>();
                }
                // 转换并添加
                MessageForDayVO forDayVO = new MessageForDayVO();
                forDayVO.setGcId(message.getGcId());
                forDayList.add(forDayVO);
            }
        }
        return resultList;
    }
}
